﻿namespace CSharpTest
{
    internal class MqttClientService
    {
        public static IMqttClient? _mqttClient = null;
        public void MqttClientStart()
        {
            var optionsBuilder = new MqttClientOptionsBuilder()
                .WithTcpServer("127.0.0.1", 1883)
                .WithCredentials("admin", "123456")
                .WithClientId("device1")
                .WithCleanSession()
                .WithTls(new MqttClientOptionsBuilderTlsParameters
                {
                    UseTls = false
                });
            var clientOptions = optionsBuilder.Build();
            _mqttClient = new MqttFactory().CreateMqttClient();

            _mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync;
            _mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync;
            _mqttClient.ApplicationMessageReceivedAsync += _mqttClient_ApplicationMessageReceivedAsync;

            _mqttClient.ConnectAsync(clientOptions);
        }

        private System.Threading.Tasks.Task _mqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
        {
            Console.WriteLine($"ApplicationMessageReceivedAsync: 发送端ID=【{arg.ClientId}】，Topic主题=【{arg.ApplicationMessage.Topic}】，消息=【{Encoding.UTF8.GetString(arg.ApplicationMessage.Payload)}】，qos等级=【{arg.ApplicationMessage.QualityOfServiceLevel}】");
            return Task.CompletedTask;
        }

        private System.Threading.Tasks.Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
        {
            Console.WriteLine($"客户端已断开与服务端的连接……， 原因：{arg.Reason}，异常：{arg.Exception}");
            return Task.CompletedTask;
        }

        private System.Threading.Tasks.Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
        {
            Console.WriteLine("客户端已连接服务端……");
            _mqttClient.SubscribeAsync("UP/device1", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
            _mqttClient.UnsubscribeAsync("UP/device1");
            _mqttClient.SubscribeAsync("UP/device1", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
            return Task.CompletedTask;
        }

        public async Task Publish(string data, string topic = "DW/device1")
        {
            if (_mqttClient == null) { return; }
            var message = new MqttApplicationMessage
            {
                Topic = topic,
                Payload = Encoding.ASCII.GetBytes(data),
                QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce,
                Retain = true,
            };
            await _mqttClient.PublishAsync(message);
        }
    }
}
